home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 February
/
EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso
/
earcd
/
comm2
/
kms20src.lha
/
KMSXPR
/
kmsxpr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-24
|
25KB
|
964 lines
/**********************************
* KMSXPR *
**********************************/
/*************************************************************************
*
* Copyright (C) 1995 Thomas Schwarz
* <kmshq@ruatha.muc.de>
* <Schwarz.Thomas@fhm.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <dos/dostags.h>
#include <dos/var.h>
#include <utility/tagitem.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include "xproto.h"
#define SEEK_SET 0
#define SEEK_CUR 1
#define SEEK_END 2
#define MAXFILES 32 /* max number of files to send in one pass */
#define ACTION_QUERY 64 /* our own action */
#define LEN_DOSPATH 127
#define LEN_MAXLINE 255
/********************
* Prototypes *
********************/
extern VOID main(UWORD argc, STRPTR *argv);
extern UWORD Break(VOID);
extern BOOL ParseArgs(VOID);
extern LONG AUXIOStatus(VOID);
extern VOID FlushInput(VOID);
extern VOID Updatelog(STRPTR file, STRPTR comment);
extern VOID convert_date(STRPTR a, time_t mytime);
extern VOID init_xprio(BOOL batch);
extern __geta4 BPTR c_fopen(STRPTR name, STRPTR mode);
extern __geta4 VOID c_fclose(BPTR fileptr);
extern __geta4 LONG c_fread(STRPTR buffer, LONG size, LONG count, BPTR fileptr);
extern __geta4 LONG c_fwrite(STRPTR buffer, LONG size, LONG count, BPTR fileptr);
extern __geta4 LONG c_finfo(STRPTR name, LONG info);
extern __geta4 LONG c_fseek(BPTR fileptr, LONG position, LONG origin);
extern __geta4 LONG c_sread(STRPTR buffer, LONG size, LONG timeout);
extern __geta4 LONG c_swrite(STRPTR buffer, LONG size);
extern __geta4 VOID c_sflush(VOID);
extern __geta4 LONG c_chkabort(VOID);
extern __geta4 LONG c_ffirst(STRPTR buf, STRPTR pattern);
extern __geta4 LONG c_fnext(LONG fstate, STRPTR buf, STRPTR template);
extern __geta4 LONG c_setserial(LONG newstatus);
extern __geta4 VOID c_chkmisc(VOID);
extern __geta4 LONG c_squery(VOID);
extern __geta4 LONG c_unlink(STRPTR name);
extern __geta4 LONG c_options(LONG n, struct xpr_option *opt[]);
extern __geta4 LONG c_gets(STRPTR prompt, STRPTR buffer);
extern __geta4 VOID c_update(struct XPR_UPDATE *ud);
extern LONG XProtocolSetup(struct XPR_IO *IO);
extern LONG XProtocolCleanup(struct XPR_IO *IO);
extern LONG XProtocolSend(struct XPR_IO *IO);
extern LONG XProtocolReceive(struct XPR_IO *IO);
extern LONG a_fopen(), a_fclose(), a_fread(), a_fwrite(),
a_finfo(), a_fseek(), a_sread(), a_swrite(),
a_sflush(), a_update(), a_chkmisc(), a_setserial(),
a_squery(), a_unlink(), a_chkabort(), a_options(),
a_gets(), a_ffirst(), a_fnext();
/********************
* Global Variables *
********************/
extern struct DosLibrary *DOSBase;
STRPTR Version = "\0$VER: KMSXPR 1.2 (" __COMMODORE_DATE__ ")";
STRPTR Title = "\nKMSXPR 1.2 -*- KMS File Transfer Server -*- (c)1993/94 Thomas Schwarz\n";
struct Library *XProtocolBase = NULL;
struct XPR_IO XPRIO;
struct RDArgs *RArgs = NULL;
struct RDArgs *MyRDArgs = NULL;
STRPTR FileNames[MAXFILES], LibName, LibOpts, FileList;
STRPTR LogDir = "T:", DefaultDir = "T:";
TEXT LogDate[18], LogMode[5], LogName[256];
BPTR OldCurrentDir = 0;
LONG LogBytes, LogSize, LogCps;
UWORD NumFiles = 0;
BOOL SendMode = FALSE;
UBYTE MaxFree = 0;
/*********************************
* Main *
*********************************/
VOID main(UWORD argc, STRPTR *argv)
{
BOOL error = FALSE;
BPTR newcurrent = NULL;
UBYTE n;
printf(Title);
if(!ParseArgs())
exit(10);
if(IsInteractive(Input()))
SetMode(Input(), 1);
/* Is DefaultDir really a directory? */
BPTR mylock;
struct FileInfoBlock *fileinfo = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock), MEMF_PUBLIC|MEMF_CLEAR);
if(!fileinfo)
printf("\r\nOut of memory!\r\n");
if(fileinfo && (mylock = Lock(DefaultDir, ACCESS_READ)))
{
if(Examine(mylock, fileinfo))
{
if(fileinfo->fib_DirEntryType <= 0) /* Not a directory */
{
printf("\r\n\"%s\" is not a directory!\r\n", DefaultDir);
error = TRUE;
}
}
else
{
printf("\r\nCould not Examine \"%s\"!\r\n", DefaultDir);
error = TRUE;
}
UnLock(mylock);
}
else
{
printf("\r\nCould not Lock \"%s\"!\r\n", DefaultDir);
error = TRUE;
}
/* Is LogDir really a directory? */
if(fileinfo && (mylock = Lock(LogDir, ACCESS_READ)))
{
if(Examine(mylock, fileinfo))
{
if(fileinfo->fib_DirEntryType <= 0) /* Not a directory */
{
printf("\r\n\"%s\" is not a directory!\r\n", LogDir);
error = TRUE;
}
}
else
{
printf("\r\nCould not Examine \"%s\"!\r\n", LogDir);
error = TRUE;
}
UnLock(mylock);
}
else
{
printf("\r\nCould not Lock \"%s\"!\r\n", LogDir);
error = TRUE;
}
if(fileinfo)
FreeMem(fileinfo, sizeof(struct FileInfoBlock));
if(!error)
{
newcurrent = Lock(DefaultDir, ACCESS_READ);
if(!newcurrent)
{
printf("\r\nFailed to set CurrentDir to \"%s\"!\r\n", DefaultDir);
error = TRUE;
}
else
OldCurrentDir = CurrentDir(newcurrent);
}
if(!error)
{
if(SendMode)
printf("\r\nSending...\r\n");
else
printf("\r\nReceiving...\r\n");
if(!SendMode) /* Receiving */
{
strcpy(LogMode, "Rcvd");
if((XProtocolBase = (struct Library *)OpenLibrary(LibName, 0)))
{
if(NumFiles == 1)
init_xprio(FALSE); /* no batch mode */
else
init_xprio(TRUE); /* batch mode */
XPRIO.xpr_filename = LibOpts;
if(XProtocolSetup(&XPRIO))
{
XPRIO.xpr_filename = FileNames[0];
*LogName = '\0';
LogBytes = 0;
LogSize = 0;
LogCps = 0;
if(!XProtocolReceive(&XPRIO))
error = TRUE;
XProtocolCleanup(&XPRIO);
}
else
{
printf("\r\nSetup error!\r\n");
error = TRUE;
}
CloseLibrary(XProtocolBase);
}
else
{
printf("\r\nCannot open %s!\r\n", LibName);
error = TRUE;
}
}
else /* Sending */
{
strcpy(LogMode, "Sent");
if((XProtocolBase = (struct Library *)OpenLibrary(LibName, 0)))
{
if(NumFiles > 1)
init_xprio(TRUE); /* batch mode */
else
init_xprio(FALSE); /* no batch */
XPRIO.xpr_filename = LibOpts;
if(XProtocolSetup(&XPRIO))
{
XPRIO.xpr_filename = NULL;
*LogName = '\0';
LogBytes = 0;
LogSize = 0;
LogCps = 0;
if(NumFiles == 1)
XPRIO.xpr_filename = FileNames[0];
if(!XProtocolSend(&XPRIO))
error = TRUE;
XProtocolCleanup(&XPRIO);
}
else
{
printf("\r\nSetup error!\r\n");
error = TRUE;
}
CloseLibrary(XProtocolBase);
}
else
{
printf("\r\nCannot open %s!\r\n", LibName);
error = TRUE;
}
}
}
if(newcurrent)
{
CurrentDir(OldCurrentDir);
UnLock(newcurrent);
}
FreeArgs(RArgs);
FreeDosObject(DOS_RDARGS, MyRDArgs);
for(n = 0; n < MaxFree; n++)
free(FileNames[n]);
Delay(50);
FlushInput();
if(error)
printf("\r\nTransfer failed.\r\n");
else
printf("\r\nTransfer completed.\r\n");
if(IsInteractive(Input()))
SetMode(Input(), 0);
exit(0);
}
/******************************************
* Break-Handler *
******************************************
* I: --- *
* O: 0 *
******************************************/
UWORD Break(VOID)
{
return 0;
}
/****************************
* Parse Arguments *
****************************
* I: --- *
* O: Error: FALSE Ok: TRUE *
****************************/
#define TEMPLATE "LIBRARY/A,OPTIONS/K,RECEIVE/S,SEND/S,LOGDIR/K,DEFDIR/K,LIST/K,FILES/M"
STRPTR HelpTxt = "\nUsage:\n\n" \
"LIBRARY/A required: name of xpr-library to use for the file transfer\n" \
" (e.g. \"xprzmodem.library\")\n" \
"OPTIONS/K optional: xpr-library options (see docs for used library)\n" \
" (e.g. OPTIONS=\"TN ON B16 F0 E10 AN DN KY SN RN PT:\")\n" \
"RECEIVE/S optional: start transfer in receive mode (default)\n" \
"SEND/S optional: start transfer in send mode\n" \
"LOGDIR/K optional: directory for transfer logging (defaults to \"T:\")\n" \
" (e.g. LOGDIR = DH0:Log)\n" \
"DEFDIR/K optional: directory for received files (default is current dir)\n" \
" (e.g. DEFDIR = Downloads:)\n" \
"LIST/K optional: file which contains, line by line, the names of\n" \
" the files to be transferred including full path\n" \
"FILES/M optional for receiving, required for sending if no LIST given:\n" \
" Receiving: name of the file to be received. If none is given,\n" \
" the name is taken from the sending side if possible\n" \
" Sending : name(s) of the file(s) to be sent\n\n";
BOOL ParseArgs(VOID)
{
UBYTE n;
ULONG args[8];
TEXT frompath[LEN_DOSPATH+1];
TEXT fline[LEN_MAXLINE+1];
FILE *flist;
for(n = 0; n < 8; n++)
args[n] = 0;
LibName = NULL;
LibOpts = NULL;
FileList = NULL;
SendMode = FALSE;
NumFiles = 0;
MyRDArgs = AllocDosObjectTags(DOS_RDARGS, TAG_DONE);
if(!MyRDArgs)
{
PrintFault(IoErr(), NULL);
return FALSE;
}
MyRDArgs->RDA_ExtHelp = HelpTxt;
if(!(RArgs = (struct RDArgs *)ReadArgs(TEMPLATE, args, MyRDArgs)))
{
PrintFault(IoErr(), NULL);
FreeDosObject(DOS_RDARGS, MyRDArgs);
return FALSE;
}
if(args[0]) /* LIBRARY/A */
LibName = (STRPTR)args[0];
if(args[1]) /* OPTIONS/K */
LibOpts = (STRPTR)args[1];
if(args[2]) /* RECEIVE/S */
SendMode = FALSE;
else
SendMode = TRUE;
if(args[3]) /* SEND/S */
SendMode = TRUE;
else
SendMode = FALSE;
if(args[4]) /* LOGDIR/A */
LogDir = (STRPTR)args[4];
if(args[5]) /* DEFDIR/A */
DefaultDir = (STRPTR)args[5];
if(args[6]) /* LIST/K */
{
BPTR lock;
FileList = (STRPTR)args[6];
/* Dateien aus Filelist einlesen */
if(!SendMode && NumFiles > 1)
{
printf("\r\nOnly batch transfer or one file in receive mode!\r\n");
FreeArgs(RArgs);
FreeDosObject(DOS_RDARGS, MyRDArgs);
return FALSE;
}
flist = fopen(FileList, "r");
if(flist)
{
while(fgets(fline, LEN_DOSPATH, flist) && NumFiles < MAXFILES-1 && (!SendMode || NumFiles < 1))
{
*frompath = '\0';
sscanf(fline, "%s", frompath);
if(lock = Lock(frompath, ACCESS_READ))
{
UnLock(lock);
FileNames[NumFiles++] = strdup(frompath);
MaxFree++;
}
else
printf("\r\n%s is not readable.\r\n", frompath);
}
fclose(flist);
if(!SendMode && NumFiles > 1)
{
printf("\r\nOnly batch transfer or one file in receive mode!\r\n");
free(FileNames[0]);
free(FileNames[1]);
FreeArgs(RArgs);
FreeDosObject(DOS_RDARGS, MyRDArgs);
return FALSE;
}
if(SendMode && !NumFiles && !args[7])
{
printf("\r\nNo files to send!?\r\n");
FreeArgs(RArgs);
FreeDosObject(DOS_RDARGS, MyRDArgs);
return FALSE;
}
FileNames[NumFiles] = NULL;
}
else
{
printf("\r\n%s not found!\r\n", FileList);
FreeArgs(RArgs);
FreeDosObject(DOS_RDARGS, MyRDArgs);
return FALSE;
}
}
if(args[7]) /* FILES/M */
{
STRPTR *files = (STRPTR *)args[7];
BPTR lock;
n = 0;
/* Angegebene Files aufnehmen */
if(!SendMode && (NumFiles > 0 || (files[0] != NULL && files[1] != NULL)))
{
printf("\r\nOnly batch transfer or one file in receive mode!\r\n");
if(NumFiles > 0)
free(FileNames[0]);
FreeArgs(RArgs);
FreeDosObject(DOS_RDARGS, MyRDArgs);
return FALSE;
}
if(SendMode)
{
while(files[n] != NULL && NumFiles < MAXFILES-1)
{
if(lock = Lock(files[n], ACCESS_READ))
{
UnLock(lock);
FileNames[NumFiles++] = files[n];
}
else
printf("\r\n%s is not readable.\r\n", files[n]);
n++;
}
if(!NumFiles)
{
printf("\r\nNo files to send!?\r\n");
FreeArgs(RArgs);
FreeDosObject(DOS_RDARGS, MyRDArgs);
return FALSE;
}
}
else
FileNames[NumFiles++] = files[n];
FileNames[NumFiles] = NULL;
}
else if(SendMode && !NumFiles)
{
printf("\r\nNo files to send!?\r\n");
FreeArgs(RArgs);
FreeDosObject(DOS_RDARGS, MyRDArgs);
return FALSE;
}
return TRUE;
}
/*********************************
* AUXIOStatus *
*********************************/
LONG AUXIOStatus(VOID)
{
DoPkt(((struct FileHandle *)BADDR(Output()))->fh_Type, ACTION_QUERY, 0, 0, 0, 0, 0);
return IoErr();
}
/****************************
* Lese-Kanal leeren *
****************************
* I: --- *
* O: --- *
****************************/
/// "FlushInput"
VOID FlushInput(VOID)
{
TEXT buff[128];
while(WaitForChar(Input(), 0) == DOSTRUE && Read(Input(), buff, sizeof(buff)) > 0);
}
///
/*********************************************/
VOID Updatelog(STRPTR file, STRPTR comment)
{
BPTR fp;
if(fp = Open(file, MODE_OLDFILE))
Seek(fp, 0, OFFSET_END);
else
fp = Open(file, MODE_NEWFILE);
if(fp)
{
Write(fp, comment, strlen(comment));
Close(fp);
}
}
/*********************************************/
VOID convert_date(STRPTR a, time_t mytime)
{
struct tm *zt;
zt = localtime(&mytime);
sprintf(a, "%02d.%02d.%02d %02d:%02d:%02d", zt->tm_mday, zt->tm_mon+1, zt->tm_year, zt->tm_hour, zt->tm_min, zt->tm_sec);
}
/*********************************************/
VOID init_xprio(BOOL batch)
{
memset((VOID *)&XPRIO, 0, (int)sizeof(XPRIO));
XPRIO.xpr_filename = NULL;
XPRIO.xpr_fopen = (VOID *)a_fopen;
XPRIO.xpr_fclose = (VOID *)a_fclose;
XPRIO.xpr_fread = (VOID *)a_fread;
XPRIO.xpr_fwrite = (VOID *)a_fwrite;
XPRIO.xpr_sread = (VOID *)a_sread;
XPRIO.xpr_swrite = (VOID *)a_swrite;
XPRIO.xpr_sflush = (VOID *)a_sflush;
XPRIO.xpr_update = (VOID *)a_update;
XPRIO.xpr_chkabort = (VOID *)a_chkabort;
XPRIO.xpr_chkmisc = (VOID *)a_chkmisc;
XPRIO.xpr_gets = (VOID *)a_gets;
XPRIO.xpr_setserial = (VOID *)a_setserial;
if(batch) /* Send: several filenames given / Receive: no file given */
{
XPRIO.xpr_ffirst = (VOID *)a_ffirst;
XPRIO.xpr_fnext = (VOID *)a_fnext;
}
XPRIO.xpr_finfo = (VOID *)a_finfo;
XPRIO.xpr_fseek = (VOID *)a_fseek;
XPRIO.xpr_extension = 3;
XPRIO.xpr_options = (VOID *)a_options;
XPRIO.xpr_unlink = (VOID *)a_unlink;
XPRIO.xpr_squery = (VOID *)a_squery;
}
/*********************************************/
__geta4 BPTR c_fopen(STRPTR name, STRPTR mode)
{
BPTR file = NULL;
TEXT dir = mode[0], mod = mode[1];
if(dir == 'a')
{
if(mod == '+')
file = Open(name, MODE_READWRITE);
else
file = Open(name, MODE_OLDFILE);
if(file)
Seek(file, 0, OFFSET_END);
}
else if(dir == 'r')
{
if(mod == '+')
file = Open(name, MODE_READWRITE);
else
file = Open(name, MODE_OLDFILE);
}
else if(dir == 'w')
file = Open(name, MODE_NEWFILE);
return(file);
}
/*********************************************/
__geta4 VOID c_fclose(BPTR fileptr)
{
Close(fileptr);
}
/*********************************************/
__geta4 LONG c_fread(STRPTR buffer, LONG size, LONG count, BPTR fileptr)
{
return Read(fileptr, buffer, size * count);
}
/*********************************************/
__geta4 LONG c_fwrite(STRPTR buffer, LONG size, LONG count, BPTR fileptr)
{
return Write(fileptr, buffer, size * count);
}
/*********************************************/
__geta4 LONG c_finfo(STRPTR name, LONG info)
{
LONG file, len = 0;
if(info == 1)
{
if(file = Open(name, MODE_OLDFILE))
{
Seek(file, 0, OFFSET_END);
len = Seek(file, 0, OFFSET_CURRENT);
Close(file);
}
}
else if(info == 2)
len = 1; /* binary file */
return(len);
}
/*********************************************/
__geta4 LONG c_fseek(BPTR fileptr, LONG position, LONG origin)
{
switch(origin)
{
case SEEK_SET:
Seek(fileptr, position, OFFSET_BEGINNING);
break;
case SEEK_CUR:
Seek(fileptr, position, OFFSET_CURRENT);
break;
case SEEK_END:
Seek(fileptr, position, OFFSET_END);
break;
}
return 0;
}
/*********************************************/
/* Get char from stdio */
/* timeout is in micros */
/* -1 == FATAL ERROR */
__geta4 LONG c_sread(STRPTR buffer, LONG size, LONG timeout)
{
int chars = 0, c;
do
{
if(WaitForChar(Input(), timeout))
{
c = Read(Input(), buffer + chars, size - chars);
if(c <= 0)
return -1; /* carrier lost? EOF? breaked? */
chars += c;
if(!timeout)
return chars;
}
else
return chars;
} while(chars < size);
return chars;
}
/*********************************************/
/* Put string to stdout */
__geta4 LONG c_swrite(STRPTR buffer, LONG size)
{
return Write(Output(), buffer, size);
}
/*********************************************/
/* Flush stdin buffer */
__geta4 VOID c_sflush(VOID)
{
TEXT flushbuffer[128];
while(WaitForChar(Input(), 0) && Read(Input(), flushbuffer, 128) > 0);
}
/*********************************************/
__geta4 LONG c_chkabort(VOID)
{
LONG state = AUXIOStatus();
if(state == -1)
return 0; /* ACTION_QUERY not implemented */
if(state & (1 << 5))
return -1; /* carrier lost */
if(state & (1 << 10))
return -1; /* break received */
return 0;
}
/*********************************************/
__geta4 LONG c_ffirst(STRPTR buf, STRPTR pattern)
{
if(!NumFiles)
return 0;
strcpy(buf, FileNames[0]);
return 1;
}
/*********************************************/
__geta4 LONG c_fnext(LONG fstate, STRPTR buf, STRPTR template)
{
if(fstate >= NumFiles)
return 0;
strcpy(buf, FileNames[fstate]);
return fstate + 1;
}
/*********************************************/
/* query/set serial params */
__geta4 LONG c_setserial(LONG newstatus)
{
/*
serial status longword:
.......................
byte 0: as the SerFlags field in IOExtSer structure.
bit 0: - parity on if set
bit 1: - parity odd if set
bit 2: - 7-wire protocol enabled if set
bit 3: - queued break if set
bit 4: - rad-boogie if set
bit 5: - shared if set
bit 6: - EOF mode if set
bit 7: - Xon/Xoff disabled if set
byte 1: summary of other settings
bit 0: - enable mark/space parity if set
bit 1: - parity mark if set, space otherwise
bit 2: - 2 stop bits if set, 1 otherwise
bit 3: - read wordlength is 7 if set, 8 otherwise
bit 4: - write wordlength is 7 if set, 8 otherwise
bit 5: - not used
bit 6: - not used
bit 7: - not used
byte 2: specifies one of a limited set of baud rates, as in
preferences.h.
- 110 baud = 0
- 300 baud = 1
- 1200 baud = 2
- 2400 baud = 3
- 4800 baud = 4
- 9600 baud = 5
- 19200 baud = 6
- midi = 7
- 38400 baud = 8
- 57600 baud = 9
- 76800 baud = 10
- 115200 baud = 11
byte 3: not used
*/
if(newstatus == -1L) /* query */
return 0x00050094; /* pseudo-result: 9600bps, Parity Off, 7WIRE, RAD_BOOGIE, XON/XOFF disabled, 8 Bits */
else /* set: Not implemented */
return -1L;
}
/*********************************************/
/* check miscellaneous stuff */
__geta4 VOID c_chkmisc(VOID)
{
return;
}
/*********************************************/
/* query serial input buffer */
__geta4 LONG c_squery(VOID)
{
if(WaitForChar(Input(), 0))
return IoErr();
return 0;
}
/*********************************************/
/* delete a file */
__geta4 LONG c_unlink(STRPTR name)
{
return DeleteFile(name);
}
/*********************************************/
__geta4 LONG c_options(LONG n, struct xpr_option *opt[])
{
return 0;
}
/*********************************************/
__geta4 LONG c_gets(STRPTR prompt, STRPTR buffer)
{
*buffer = '\0';
return 0;
}
/*********************************************/
__geta4 VOID c_update(struct XPR_UPDATE *ud)
{
TEXT buffer[128];
TEXT logpath[LEN_DOSPATH+1];
TEXT slash[2];
LONG a = ud->xpru_updatemask;
if(a & XPRU_FILENAME)
strcpy(LogName, ud->xpru_filename);
if(a & XPRU_FILESIZE)
LogSize = ud->xpru_filesize;
if(a & XPRU_BYTES)
{
LogBytes = ud->xpru_bytes;
if(LogSize != -9) /* if not already logged */
{
/* e.g. XModem -> No filesize given! */
if((LogBytes > 0 && LogBytes == LogSize) || LogSize == -1)
{
convert_date(LogDate, time(NULL));
if(DefaultDir[strlen(DefaultDir)-1] != ':' && DefaultDir[strlen(DefaultDir)-1] != '/')
strcpy(slash, "/");
else
strcpy(slash, "");
sprintf(buffer, "%s %ld %ld %s %s\n", LogName, LogSize, LogCps, LogMode, LibName);
strcpy(logpath, LogDir);
if(logpath[strlen(logpath)-1] != ':' && logpath[strlen(logpath)-1] != '/')
strcat(logpath, "/");
strcat(logpath, "KMSXPR.LOG");
Updatelog(logpath, buffer);
LogSize = -9; /* already updated */
}
}
}
if(a & XPRU_DATARATE)
LogCps = ud->xpru_datarate;
}